package com.coffee.socket;

import com.coffee.util.JwtUtils;
import io.jsonwebtoken.Claims;
import lombok.extern.slf4j.Slf4j;

import javax.websocket.*;
import javax.websocket.server.PathParam;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.CopyOnWriteArraySet;
@Slf4j
public class WebSocketServer {
    //与某个客户端的连接会话，需要通过它来给客户端发送数据
    private Session session;

    private static CopyOnWriteArraySet<WebSocketServer> webSockets = new CopyOnWriteArraySet<>();
    //用来存放每个客户端对应的WebSocket对象。
    private static Map<String, Session> sessionPool = new HashMap<>();

    /**
     * 连接成功后调用的方法
     *
     * @param session
     * @param key
     */
    @OnOpen
    public void onOpen(Session session, @PathParam("key") String key) throws IOException {
        //key为前端传给后端的token
        this.session = session;
        //从token中获取到userid当做区分websocket客户端的key
        Claims claims = JwtUtils.parseJWT(key);
        String userId = claims.get("id").toString();
        sessionPool.put(String.valueOf(userId), session);
        if (sessionPool.get(String.valueOf(userId)) == null) {
            webSockets.add(this);
        }
        webSockets.add(this);
        System.out.println("webSocket连接成功");
        System.out.println("WebSocket有新的连接，连接总数为：" + webSockets.size());
    }

    /**
     * 连接关闭调用的方法
     */
    @OnClose
    public void onClose() {
        webSockets.remove(this);
        System.out.println("webSocket连接关闭");
    }

    /**
     * 收到客户端消息后调用的方法，根据业务要求进行处理，这里就简单地将收到的消息直接群发推送出去
     *
     * @param message 客户端发送过来的消息
     */
    @OnMessage
    public void onMessage(String message) {
        //心跳检测
        int beginIndex = 10;
        if ("HeartBeat".equals(message.substring(0, 9))) {
            String token = message.substring(beginIndex);
            System.out.println("token1" + token);
            if (!"".equals(token)) {
                System.out.println("token2" + token);
                //从token中获取到userid当做区分websocket客户端的key
                Claims claims = JwtUtils.parseJWT(token);
                String userId = claims.get("id").toString();
                sendTextMessage(String.valueOf(userId), "ok");
            }
        }
        System.out.println("WebSocket收到客户端消息：" + message);
    }

    /**
     * 发生错误时的回调函数
     *
     * @param session
     * @param error
     */
    @OnError
    public void onError(Session session, Throwable error) {
        log.error("发生错误");
        error.printStackTrace();
    }

    /**
     * 实现服务器主动推送消息
     */
    //单点消息发送
    public void sendTextMessage(String key, String message) {
        Session session = sessionPool.get(key);
        if (session != null) {
            try {
                session.getBasicRemote().sendText(message);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
}
